package com.innovate.cms.modules.qs.web.order;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.ZhimaCreditScoreGetRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.ZhimaCreditScoreGetResponse;
import com.innovate.cms.common.config.Global;
import com.innovate.cms.common.mapper.JsonMapper;
import com.innovate.cms.common.utils.StrUtil;
import com.innovate.cms.common.web.BaseController;
import com.innovate.cms.modules.common.entity.BaseBackInfo;
import com.innovate.cms.modules.common.entity.ItemBackInfo;
import com.innovate.cms.modules.common.entity.TradeBackInfo;
import com.innovate.cms.modules.qs.entity.msg.DynamicMsgForService;
import com.innovate.cms.modules.qs.entity.order.AlipayConfig;
import com.innovate.cms.modules.qs.entity.order.DbOrder;
import com.innovate.cms.modules.qs.service.msg.DynamicMsgService;
import com.innovate.cms.modules.qs.service.order.DbOrderService;

/**
 * 微信支付
 * 
 * @author shifangfang
 * @date 2018年1月8日 下午6:02:17
 */
@Controller
@RequestMapping(value = "/api/alipay")
public class AliPayController extends BaseController {
	@Autowired
	private DbOrderService dbOrderService;
	@Autowired
	private DynamicMsgService dynamicMsgService;

	// 实例化客户端
	static AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

	/**
	 * 生成16位订单号
	 * 
	 * @return
	 */
	public static String genTradeNo() {
		int first = new Random().nextInt(8) + 1;
		int hashCodeV = UUID.randomUUID().toString().hashCode();
		if (hashCodeV < 0) {// 有可能是负数
			hashCodeV = -hashCodeV;
		}
		return first + String.format("%015d", hashCodeV);
	}

	/**
	 * @param userId
	 *            充值人
	 * @param tradeMoney
	 *            充值money(RMB)
	 * @throws AlipayApiException
	 *             ModelAndView
	 */
	@RequestMapping(value = "/pay", method = { RequestMethod.POST, RequestMethod.GET })
	public @ResponseBody BaseBackInfo alipay(@RequestBody Map<String, String> map, HttpServletRequest req, HttpServletResponse response) throws AlipayApiException {
		TradeBackInfo backInfo = new TradeBackInfo();
		System.err.println("进入ali支付申请");

		String url = req.getRequestURL().toString();
		String notify_url = req.getRequestURL().substring(0, url.lastIndexOf("/")) + "/notify";
		logger.info("notify_url:" + notify_url);
		String priceStr = map.get("price");
		String title = map.get("title");
		String user_id = map.get("consumerUid");
		String coupon_id = map.get("mid");
		String mobile = map.get("mobile");
		String num = map.get("num");
		// 首先判断是否过期
		// int consumeState = 1;
		Calendar now = Calendar.getInstance();
		// now.set(Calendar.HOUR_OF_DAY, 23);
		// now.set(Calendar.MINUTE, 59);
		// now.set(Calendar.SECOND, 59);
		// 获取消息详情
		DynamicMsgForService msg = dynamicMsgService.msgInfo(Integer.parseInt(coupon_id));
		// 如果订单有效时间小于当前时间，说明已经过期
		if (msg.getMsgEndDate().getTime() < now.getTimeInMillis()) {
			logger.info("消费时间过期,无法消费! mid:" + coupon_id + " title:" + map.get("title"));

			BaseBackInfo info = new BaseBackInfo();
			info.setStateCode(Global.intNO);
			info.setRetMsg("消费时间过期,无法消费!");
			return info;
		}

		if (StrUtil.isBlank(user_id) || StrUtil.isBlank(user_id) || StrUtil.isBlank(coupon_id) || StrUtil.isBlank(title)) {
			BaseBackInfo info = new BaseBackInfo();
			info.setStateCode(Global.int300209);
			info.setRetMsg(Global.str300209);
			return info;
		}

		DbOrder dbOrder = new DbOrder();

		String out_trade_no = genTradeNo(); // 需要前端给的参数
		// 生成订单号
		dbOrder.setTradeNo(out_trade_no);
		dbOrder.setConsumerUid(user_id);
		dbOrder.setMobile(mobile);
		dbOrder.setMid(Integer.parseInt(coupon_id));
		dbOrder.setPrice(Double.valueOf(priceStr));
		dbOrder.setNum(Integer.parseInt(num));
		// 支付宝支付设置为1
		dbOrder.setPayType(1);

		// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		// SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(coupon_id + ":" + title);
		model.setSubject(title);
		model.setOutTradeNo(out_trade_no);
		model.setTimeoutExpress("30m");
		model.setTotalAmount(priceStr);
		model.setProductCode("QUICK_MSECURITY_PAY");
		request.setBizModel(model);
		request.setNotifyUrl(notify_url);
		try {
			// 这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse res = alipayClient.sdkExecute(request);
			System.out.println(res.getBody());// 就是orderString
												// 可以直接给客户端请求，无需再做处理。
			// 存储预支付订单
			dbOrderService.saveOrder(dbOrder);

			backInfo.setStateCode(Global.intYES);
			backInfo.setRetMsg(Global.SUCCESS);
			backInfo.setItem(res.getBody());
			backInfo.setTradeNo(out_trade_no);
		} catch (AlipayApiException e) {
			e.printStackTrace();
			BaseBackInfo info = new BaseBackInfo();
			info.setStateCode(-1);
			info.setRetMsg(Global.ERROR);
			return info;
		}

		return backInfo; // 给前端app返回此字符串，再调用前端的微信sdk引起微信支付
	}

	/**
	 * 订单支付异步通知
	 */
	@SuppressWarnings("rawtypes")
	@RequestMapping(value = "/notify", method = { RequestMethod.GET, RequestMethod.POST })
	public @ResponseBody BaseBackInfo aliPayBack(HttpServletRequest request, HttpServletResponse response) {
		try {
			ItemBackInfo backInfo = new ItemBackInfo();

			// 获取支付宝POST过来反馈信息
			Map<String, String> params = new HashMap<String, String>();
			Map requestParams = request.getParameterMap();
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "utf-8");
				params.put(name, valueStr);
			}
			// 切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
			// boolean AlipaySignature.rsaCheckV1(Map<String, String> params,
			// String publicKey, String charset, String sign_type)
			boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);

			// 把预支付订单状态改为成功支付
			// 订单状态
			// 0-预支付订单(微信淘宝的预支付,在没确认回调成功之前的状态)
			// 1-成功支付的订单
			if (flag) {
				backInfo.setStateCode(Global.intYES);
				backInfo.setRetMsg(Global.SUCCESS);
				backInfo.setItem(params);
				int orderState = 1;
				dbOrderService.updateOrderState(params.get("out_trade_no"), orderState, JsonMapper.toJsonString(params));
			} else {

				backInfo.setStateCode(-1);
				backInfo.setRetMsg("异步通知ALIPAY_PUBLIC_KEY验签失败");
				return backInfo;
			}

			return backInfo;
		} catch (Exception e) {
			logger.error("手机支付回调通知失败", e);
			BaseBackInfo backInfo = new BaseBackInfo();
			backInfo.setStateCode(-1);
			backInfo.setRetMsg(Global.ERROR);
			return backInfo;
		}
	}

	@RequestMapping(value = "/zhimaScore", method = RequestMethod.POST)
	public @ResponseBody BaseBackInfo zhimaScore(@RequestBody Map<String, String> map, HttpServletRequest req, HttpServletResponse resp) {

		String umid = map.get("umid");

		ZhimaCreditScoreGetRequest request = new ZhimaCreditScoreGetRequest();
		request.setBizContent("{" + " \"transaction_id\":\"201512100936588040000000465158\"," + " \"product_code\":\"w1010100100000000001\"" + " }");
		ZhimaCreditScoreGetResponse response;
		try {
			response = alipayClient.execute(request, "accessToken");
			if (response.isSuccess()) {
				System.out.println("调用成功");
				// 取得芝麻分
				System.out.println("芝麻分=" + response.getZmScore());
			} else {
				System.out.println("调用失败");
				// 处理各种异常
				System.out.println("查询芝麻分错误 code=" + response.getCode());
			}
		} catch (AlipayApiException e1) {
			e1.printStackTrace();
		}

		BaseBackInfo backInfo = new BaseBackInfo();
		if (StrUtil.isBlank(umid)) {
			BaseBackInfo info = new BaseBackInfo();
			info.setStateCode(Global.int300209);
			info.setRetMsg(Global.str300209);
			return info;
		}
		try {

			backInfo.setStateCode(Global.intYES);
			backInfo.setRetMsg(Global.SUCCESS);
		} catch (Exception e) {
			logger.debug("[" + Thread.currentThread().getStackTrace()[1].getClassName() + " - " + Thread.currentThread().getStackTrace()[1].getMethodName() + "()接口报错：{}]", e.getMessage());
			backInfo.setRetMsg(Global.ERROR);
			backInfo.setStateCode(Global.intNO);
		}
		return backInfo;
	}

}
